import { useComponentConfigStore } from "@/stores/low-editor-comps-conf";
import { Component, useComponentsStore, ComponentUnitType, getComponentById } from "@/stores/edit-pages-store";
import { createElement, MouseEventHandler, useEffect, useState } from "react";
import { useBoolean } from "ahooks";
import HoverMask from "./HoverMask";
import SelectedMask from "./SelectedMask";
import { Empty } from "antd";

export function EditArea() {
  const {
    schema,
    curComponentId,
    curComponent,
    setCurComponentId,
    popEditing,
    curPopTarget,
    setCurComponentUnitType,
    curComponentUnitType,
  } = useComponentsStore();
  const [hoverComponentId, setHoverComponentId] = useState<string>();
  const [hoverComponentUnitType, setHoverComponentUnitType] = useState<ComponentUnitType>();
  const { flatComponentConfig } = useComponentConfigStore();
  const componentConfig = flatComponentConfig();
  const [showSelect, { setTrue, setFalse }] = useBoolean(false);
  function renderComponents(components: Component[], containerUnitType: ComponentUnitType = "body"): React.ReactNode {
    return components.map(component => {
      const config = componentConfig?.[component.name];
      if (!config?.dev) null;
      const defaultProps = typeof config?.defaultProps === "function" ? config.defaultProps() : config.defaultProps;
      return createElement(
        config?.dev,
        {
          key: component.id,
          id: component.id,
          name: component.name,
          desc: component.desc,
          alias: component.alias,
          styles: component.styles,
          customClassStyle: component.customClassStyle,
          ...defaultProps,
          ...component.props,
          innerName: component.innerName,
          header: renderComponents(component?.header || [], "header"),
          aside: renderComponents(component?.aside || [], "aside"),
          footer: renderComponents(component?.footer || [], "footer"),
          buttonGroup: renderComponents(component?.buttonGroup || [], "buttonGroup"),
          containerUnitType,
        },
        renderComponents(component.body || [])
      );
    });
  }

  const handleMouseOver: MouseEventHandler = e => {
    const path = e.nativeEvent.composedPath();
    for (let i = 0; i < path.length; i++) {
      const ele = path[i] as HTMLElement;
      const componentId = ele.dataset?.componentId;
      let type = ele.dataset?.componentUnitType || undefined;
      if (componentId) {
        setHoverComponentId(componentId);
        setHoverComponentUnitType(type as ComponentUnitType);
        return;
      }
    }
  };
  const handleClick: MouseEventHandler = e => {
    const path = e.nativeEvent.composedPath();
    for (let i = 0; i < path.length; i++) {
      const ele = path[i] as HTMLElement;
      const componentId = ele.dataset?.componentId;
      const type = ele.dataset?.componentUnitType || ele.dataset?.componentBindUnit || undefined;
      if (componentId) {
        setCurComponentId(componentId);
        setCurComponentUnitType(type as ComponentUnitType);
        return;
      }
    }
  };

  /* 必须在加载后才会显示选中蒙层，不然会报渲染错误 */
  useEffect(() => {
    if (!curComponent || !curComponentId) {
      setFalse();
    } else {
      setTrue();
    }
  }, [curComponentId]);

  return (
    <div className="flex flex-col bg-gray-100 h-full">
      <header className="bg-gray-50">页面</header>
      <main className="flex-1 p-4">
        <div
          className={`h-full edit-area relative`}
          onMouseOver={handleMouseOver}
          onMouseLeave={() => {
            setHoverComponentId(undefined);
          }}
          onClick={handleClick}
        >
          {popEditing ? curPopTarget && renderComponents([curPopTarget]) : renderComponents([schema])}

          {hoverComponentId &&
            (hoverComponentId !== curComponentId ||
              (hoverComponentId === curComponentId && curComponentUnitType !== (hoverComponentUnitType ?? "body"))) && (
              <HoverMask
                portalWrapperClassName="portal-wrapper"
                containerClassName="edit-area"
                componentId={hoverComponentId}
                componentUnitType={hoverComponentUnitType}
              />
            )}
          {curComponentId && showSelect && (
            <SelectedMask
              portalWrapperClassName="portal-wrapper"
              containerClassName="edit-area"
              componentId={curComponentId}
            />
          )}
          <div className="portal-wrapper"></div>
        </div>
      </main>
    </div>
  );
}
